方法重载和方法重写

Java 方法重载与方法重写的区别

方法重载(Overloading)方法重写(Overriding) 是 Java 中的两种常见概念,它们看似相似,但在行为和实现上有很大的区别。

1. 方法重载(Overloading)

方法重载是在同一个类中,允许有多个同名方法,只要它们的参数列表不同(参数个数、类型或顺序不同)。重载主要是通过方法的签名来区分,签名包括方法的名称和参数列表,但不包括返回类型。

  • 发生地点:在同一个类中。
  • 参数列表:方法重载要求方法的参数个数、类型或顺序不同,返回类型无关。
  • 返回类型:可以不同。
  • 访问修饰符:不受限制,方法重载的访问修饰符可以是任何类型。
  • 静态和非静态:可以是静态方法或非静态方法。
  • 异常:方法的异常可以不同。

重载示例:

public class OverloadingExample {
    // 重载方法:参数数量不同
    public void print(int a) {
        System.out.println("Printing int: " + a);
    }

    // 重载方法:参数类型不同
    public void print(String a) {
        System.out.println("Printing String: " + a);
    }

    // 重载方法:参数类型和数量不同
    public void print(int a, int b) {
        System.out.println("Printing two ints: " + a + ", " + b);
    }
}

在上述代码中,print() 方法有三种重载形式,参数类型和数量不同,但它们的返回类型是相同的。


2. 方法重写(Overriding)

方法重写是指子类在继承父类时,重新定义父类的方法(方法名、参数列表必须相同),以提供特定的实现。方法重写主要用于实现多态性,即同一方法在不同对象上的行为不同。

  • 发生地点:在继承关系的子类和父类之间。
  • 参数列表:必须相同,不能改变参数列表。
  • 返回类型:必须与父类方法的返回类型相同,或者是父类返回类型的子类(协变返回类型)。
  • 访问修饰符:子类方法的访问修饰符不能比父类更严格,通常可以是相同或更宽泛(如父类为 protected,子类可以是 public)。
  • 静态和非静态:只能重写非静态方法,静态方法不能被重写(但静态方法可以被隐藏)。
  • 异常:子类的异常不能抛出比父类更多的异常,可以抛出更少的或相同类型的异常。

重写示例:

class Parent {
    public void display() {
        System.out.println("Parent display");
    }
}

class Child extends Parent {
    @Override
    public void display() {
        System.out.println("Child display");
    }
}

public class OverridingExample {
    public static void main(String[] args) {
        Parent obj = new Child();
        obj.display(); // 输出 "Child display"
    }
}

在上面的代码中,Child 类重写了 Parent 类的 display() 方法。当 Parent 类型的引用指向 Child 对象时,调用的是子类 Child 中的 display() 方法,这实现了运行时多态性


方法重载与方法重写的区别总结

区别 方法重载(Overloading) 方法重写(Overriding)
发生的场所 在同一个类中 在继承关系的子类和父类之间
参数列表 必须不同(参数的个数、类型或顺序不同) 必须相同,不能改变参数列表
返回类型 可以不同 必须与父类方法的返回类型相同,或是父类返回类型的子类(协变返回类型)
访问修饰符 不受访问修饰符影响 子类方法的访问修饰符不能比父类更严格
静态和非静态 可以是静态方法或非静态方法 只能重写非静态方法,静态方法不能被重写(静态方法可以被隐藏)
异常处理 方法的异常处理可以不同 子类的异常不能抛出比父类更多的异常(可以抛出更少的或相同类型的异常)

扩展知识

方法重载注意点

  • 签名:方法重载是根据方法的签名来区分的,而签名包括方法名和参数列表,但不包括返回类型。
  • 常见应用:重载通常用于提供同一操作的不同实现,如处理不同类型的输入数据,或者对构造函数进行重载以创建对象的不同方式。

方法重写注意点

  • @Override 注解:使用 @Override 注解可以帮助编译器检查方法是否正确地重写了父类的方法,避免错误地重写或没有重写。
  • 多态性:方法重写通常与多态性结合使用,通过父类类型的引用指向子类对象,实现动态方法调用(运行时多态)。

总结

  • 方法重载 允许在同一个类中定义多个方法,方法名相同但参数列表不同,用于提供相同操作的不同实现。
  • 方法重写 允许子类重新定义从父类继承来的方法,以提供新的实现,通常用于实现多态性。
  • 重载 关注方法签名的变化,而 重写 关注继承关系中的方法实现的修改。

相关笔记

重写/重载的完整规则(两同两小一大、@Override、常见坑)见 重写与重载;多态绑定时机见 编译时多态和运行时多态


⬅️ 接口多实现 🏠 00-Java ➡️ 编译时多态和运行时多态